package flydb

import (
	"bufio"
	"encoding/binary"
	"io"
	"log"
	"net"
	"sync"
	"time"
)

const connInterval = 8

type Server struct {
	closed   bool
	mu       sync.Mutex
	done     chan struct{}
	listener net.Listener
}

func NewServer(addr string) *Server {
	return &Server{done: make(chan struct{})}
}

func (s *Server) Listen(addr string) {
	var err error
	s.listener, err = net.Listen("tcp", addr)
	if err != nil {
		log.Printf("tcp listen err: %s\n", err.Error())
		return
	}

	log.Println("flydb is running, read to accept connections.")
	for {
		select {
		case <-s.done:
			return
		default:
			conn, err := s.listener.Accept()
			if err != nil {
				continue
			}
			go s.handleConn(conn)
		}
	}
}

func (s *Server) handleConn(conn net.Conn) {
	defer conn.Close()
	for {
		_ = conn.SetReadDeadline(time.Now().Add(time.Hour * connInterval))

		bufReader := bufio.NewReader(conn)
		b := make([]byte, 4)
		_, err := bufReader.Read(b)
		if err != nil {
			if err != io.EOF {
				log.Printf("read cmd size err: %s\n", err.Error())
			}
			break
		}

		size := binary.BigEndian.Uint32(b[:4])
		if size > 0 {
			data := make([]byte, size)
			_, err := bufReader.Read(data)
			if err != nil {
				log.Printf("read cmd data err: %s\n", err.Error())
				break
			}

			log.Printf("命令为: %s", string(data))
		}
	}
}
